package jupiter.filters;

import java.util.ArrayList;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import jupiter.channel.*;
import jupiter.message.Message;
import jupiter.message.NotRegisteredException;

import jupiter.servlets.SessionListener;
import jupiter.util.Application;
import jupiter.util.Timey;

import org.json.JSONException;
import org.json.JSONObject;
import org.mortbay.util.ajax.Continuation;
import org.mortbay.util.ajax.ContinuationSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SessionFilter {
	Logger logger = LoggerFactory.getLogger(SessionFilter.class);
	public static int TIMEOUT_SECS = 45;
	public static int SESSION_TIMEOUT = 59;
	/**
	 * Creates a session that can get messages.
	 * @param message a create session message
	 * <pre>{
	 *     type : "session",
	 *     action : "create",
	 *     data : {
	 *          address: "yourdomain.com/users/JustinMeyer#abcdef@jabbify.com",
	 *          secret : "SECRET KEY" -> optional,
	 *			temporary : true | false -> if this is a temporary session
	 *          publicInfo : {
	 *             website: "hankshomepage.com"
	 *          }
	 *     }
	 * }</pre>
	 * @return if successful returns the channel's data with any optional params filled in
	 * <pre>     
	 *    {
	 *          message: "session created successfully",
	 *          jsessionid: "XFSFIENFNFSFD", //use to connect to this sesion
	 *          parentChannel : { ... parentChannel publicIfno ... },
	 *          publicInfo : {
	 *          	referer : ""
	 *              createdAt : 12345678 -> time since epoch
	 *              ipaddress : 241.131.325.242
	 *          }
	 *     }</pre>
	 * @throws FilterException
	 */
	public JSONObject create(Message message) throws FilterException{
		logger.warn("Session::Create");
		//first lets create the session, if later the sessionChannel has a problem, not a big deal, it will 
		//be cleaned up	
		if(!message.isRegistered())
			throw new FilterException("{error: 'Not registered'}");
		if(!message.isFileSystem() && message.isBannedUser())
			throw new FilterException("{error: 'Cant add user session'}");
		HttpSession session = message.request.getSession(true);
//		logger.info("Creating session: "+session.getId());
		session.setMaxInactiveInterval(SessionFilter.TIMEOUT_SECS+SessionFilter.SESSION_TIMEOUT);
		
		//lets make sure this is a new session
		if(!session.isNew()) throw new FilterException("{error: 'session already created'}");
		
		//now create the new channel (which will attach itself to the 'user' and Domain's address book
		Session sessionChannel = new Session(message);
		//add it to the session (so it can be deleted correctly)
		session.setAttribute("sessionChannel",sessionChannel);
		
		//finally, return the session id so someone can connect
		JSONObject sending = new JSONObject();
		try{
			sending.put("message", "session created successfully");
			sending.put("jsessionid", session.getId());
			sending.put("parentChannel", sessionChannel.parentChannel().toJSON(false)); //might not be public info
		}catch(JSONException e){
			//logger.error("JSONException", e);
			throw new FilterException("{error: 'Can not add session id'}");
		}
		return sending;
	}
	//createInbox, should update 
	public JSONObject createInbox(Message message) throws FilterException{
		if(Application.isJabbifyNode()) throw new FilterException(); //make sure these don't get sent out
		
		//update the session info
		//GlobalChannel.getDomain(message.to()).getOrCreateChannelList(message.to()).addSessionData(message.data);
		
		throw new FilterException();
	}
	
	public JSONObject connect(Message message) throws FilterException{
		//System.out.println(" Connecting ...");
		String result = null;
		Session sessionChannel = null;
		HttpSession session = null;
		HttpServletRequest req = message.request;
		if(!req.isRequestedSessionIdValid())
			throw new FilterException("{error: 'Your session has been inactivated'}");
		
		session = req.getSession(false);
		if(session == null)
			throw new FilterException("{error: 'You must create a session first'}");
		
		sessionChannel = (Session) session.getAttribute("sessionChannel");
		if(sessionChannel == null)
			throw new FilterException("{error: 'Your session does not have a user!'}");
		
		result = sessionChannel.getMessages();  //sees if there are messages, if there is a current session get rid of it

		
		if(result == null){ //lets try again when something comes in
			Continuation c = ContinuationSupport.getContinuation(req,null);
			sessionChannel.addContinuation(c);
			c.suspend( SessionFilter.TIMEOUT_SECS*1000 ); //throws error
			
			//ApplicationAddressBook.addContinuation(c, session, TIMEOUT_SECS);
		}
//		logger.info("CONNECT: "+result);
		throw new FilterException(result, false); //avoid resuming continuation, and sending to everyone
		//return result;
	}
	
	// used when banning a user from the admin side
	public JSONObject invalidateInbox(Message message){
		// get the Session object
		Channel ch = (Channel) Global.getDomain(message.from() ).getChannel(message.from());
		ch.invalidateSessions();
		return null;
		
	}
	
	public JSONObject destroy(Message message)throws FilterException{
		logger.warn("Session::Destroy");
		HttpServletRequest req = message.request;
		if(!req.isRequestedSessionIdValid())
			throw new FilterException("{error: 'Your session has been inactivated'}");
		HttpSession session = req.getSession(false);
		if(session == null){
			throw new FilterException("{error: 'no session, have you created one and used that jsession id to connect?'}");
		}
		Session s = (Session) session.getAttribute("sessionChannel");
		if(s == null){
			throw new FilterException("{error: 'no session, have you created one and used that sessionid to connect?'}");
		}
		s.resume();
		s.invalidate(session);
		//session.invalidate();
		return message.json;
	}
	public JSONObject pause(Message message) throws FilterException{
		System.out.println("RESUMING----------------------------------------->");
		HttpServletRequest req = message.request;
		HttpSession session = req.getSession(false);
		if(session == null){
			throw new FilterException("{error: 'no session, have you created one and used that jsession id to connect?'}");
		}
		Session s = (Session) session.getAttribute("sessionChannel");
		if(s == null){
			throw new FilterException("{error: 'no session, have you created one and used that sessionid to connect?'}");
		}
		s.resume();
		throw new FilterException(); // avoid sending
	}
	
}
